/*
 * Copyright (c) 2009 LastFM.Desktop Anton Pavlik.
 * All Rights Reserved.
 * 
 * You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, 
 * with or without modifications, and in Source or Object form, provided that You meet the following 
 * conditions:
 * 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and
 *
 * 2. You must cause any modified files to carry prominent notices stating that You changed the files; 
 * and
 *
 * 3. You must retain, in the Source form of any Derivative Works that You distribute, all copyright, 
 * patent, trademark, and attribution notices from the Source form of the Work, excluding those notices 
 * that do not pertain to any part of the Derivative Works.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); 
 * You may not use this file except in compliance with the License. 
 * You may obtain a copy of the License at 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0 
 *
 * Unless required by applicable law or agreed to in writing, Licensor provides the Work 
 * (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
 * CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties 
 * or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. 
 * YOU ARE SOLELY RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING OR REDISTRIBUTING THE WORK
 * AND ASSUME ANY RISKS ASSOCIATED WITH YOUR EXERCISE OF PERMISSIONS UNDER THIS LICENSE. 
 */
package org.shake.lastfm.net;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.bushe.swing.event.EventBus;
import org.shake.lastfm.data.MP3Info;
import org.shake.lastfm.event.CapturingProgressEvent;
import org.shake.lastfm.event.EventTopic;
import org.shake.lastfm.event.TrackInfoObtainedEvent;
import org.shake.lastfm.model.Track;

public class TrackRipperEngine
{
    private final static String FILE_EXT = ".mp3";
    private Log log = LogFactory.getLog(TrackRipperEngine.class);
    
    public void capture(final Track track) throws HttpEngineException 
    {
        InputStream lastIn = null;
        try
        {
            lastIn = HttpEngine.getInstance().executeGet( track.getLocation() );
        } 
        catch (HttpEngineException e)
        {
            log.error(e);
            throw new HttpEngineException(e);
        }

        final int bufferSize = 1024 * 32;
        final byte[] buffer = new byte[bufferSize];

        FileOutputStream fileStream = null;
        try
        {
            File newSongFile = new File(track.getTrackName() + FILE_EXT);
            fileStream = new FileOutputStream(newSongFile);
            int bytesRead = 0;
            log.info("Start reading from stream: " + track.getLocation());
            MP3Info mp3Info = null;
            while ((bytesRead = lastIn.read(buffer)) != -1)
            {
                EventBus.publish(EventTopic.TRACK_CAPTURING_PROGRESS, new CapturingProgressEvent(bytesRead));
                fileStream.write(buffer, 0, bytesRead);
                
                if (mp3Info == null)
                {
                    mp3Info = new MP3Info(newSongFile);
                    if (mp3Info.getBitRate() == 0)
                    {
                        mp3Info = null;
                    }
                    else
                    {
                        EventBus.publish(EventTopic.TRACK_TRACKINFO_OBTAINED, new TrackInfoObtainedEvent(mp3Info));
                    }
                }
            }
        } catch (IOException e)
        {
            log.error(e);
        } finally
        {
            if (fileStream != null)
            {
                try
                {
                    fileStream.close();
                    lastIn.close();
                } catch (IOException e)
                {
                    log.warn("Could not close the stream", e);
                }
            }
        }
    }
}